///\todo upgrade

//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef __BUOLA_PYTHON_COBJECT_H_
#define __BUOLA_PYTHON_COBJECT_H_

#include <buola/python/ctype.h>
#include <buola/python/cobjectbase.h>
#include <buola/python/types.h>

namespace buola { namespace python {

template<class tType>
class CObject : public CObjectBase
{
    typedef CObject<tType> tBase;

protected:
    CObject()
        : CObjectBase(mType)
    {
        msg_debug<10>() << "creating python object of type " <<
                                    mType->mName << "\n";
    }
    
    virtual ~CObject()
    {
        msg_debug<10>() << "destroying python object of type " <<
                                    mType->mName << "\n";
    }

    static tType *GetInstanceFromPyObject(PyObject *pSelf)
    {
        return (tType*)GetBuolaPythonObject(pSelf);
    }

    static CObjectBase *NewObject(PyObject *pArgs)
    {
        tType *lObject=tType::PythonConstructorWrapper(pArgs);
        
        return lObject;
    }

    static tType *PythonConstructorWrapper(const YObject &pArgs)
    {
        throw XNotImplemented("can't create instances of this object");
    }

public:
    static void InitType(YModule &pModule,bool pAdd=true)
    {
        if(mType) return;
        
        mType=new CType(pModule.GetName(),tType::mPythonTypeName,NewObject);
        
        tType::AddMethods();
        
        mType->Init();

        if(pAdd)
            pModule.AddObject(tType::mPythonTypeName,mType->GetPythonObject());
    }

public:
    static CType *mType;
};

template<class tType>
CType *CObject<tType>::mType=nullptr;

/*namespace python*/ } /*namespace buola*/ }

#endif
